package com.t.bricks.bussiness.db.dao.goodsmake.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import com.t.bricks.bussiness.db.dao.goodsmake.GoodsMakeDao;
import com.t.bricks.bussiness.db.entity.goodsmake.GoodsMake;
import com.t.bricks.bussiness.db.entity.goodsmake.base.GoodsMakeBase;
import com.t.bricks.bussiness.db.mapper.goodsmake.GoodsMakeMapper;
import com.t.bricks.bussiness.model.goodsmake.ConditionGoodsMake;
import com.t.bricks.model.Log;
import com.t.bricks.model.MsgEmity;
import com.t.bricks.model.OrderInfoList;
import com.t.bricks.model.Page;
import com.t.bricks.utils.function.data.IntegerUtil;
import com.t.bricks.utils.function.system.ClassUtil;

@Repository
public class GoodsMakeDaoImpl implements GoodsMakeDao {
	
	@Autowired
	private GoodsMakeMapper goodsMakeMapper;

	@Value("${app.findPage.dLikeDate:配置文件中的当前库全文检索时间范围dLikeDate未设置}")
	private String sLikeDate;

	/**
	 * 添加
	 * @param goodsMake
	 * @return MsgEmity
	 */
	@Transactional
	@Override
	public MsgEmity add(GoodsMake goodsMake) {
		int code = 7000;
		try {
			int i = goodsMakeMapper.add(goodsMake);
			if (i < 1) {
				Log.error("新增未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "新增数据失败！", 7001);
			}
			
			i = goodsMakeMapper.createStockIn(goodsMake.getsId());
			if (i < 1) {
				Log.error("创建入库记录未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "新增数据失败！", 7002);
			}
			
			i = goodsMakeMapper.findStock(goodsMake.getsId());//检查是否存在库存记录
			if (i < 1) {//库存记录不存在
				i = goodsMakeMapper.createStock(goodsMake.getsId());//根据入库信息创建库存记录
				if (i != 1) {
					code = 7003;
					Log.error("创建库存记录未能得到预期影响值(预期1):", i);
					throw new RuntimeException("新增时创建对应的库存记录失败！");
				}
			} else {//库存记录已经存在
				i = goodsMakeMapper.incStock(goodsMake.getsId());//根据入库信息添加库存数量
				if (i != 1) {
					code = 7004;
					Log.error("修改库存数量未能得到预期影响值(预期1):", i);
					throw new RuntimeException("新增时修改对应的库存数量失败！");
				}
			}
		} catch (Exception e) {
			Log.error("新增时发生异常:", e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚
			return new MsgEmity(false, "新增失败！", code);
		}
		
		return new MsgEmity(true, "新增成功！", goodsMake);
	}

	/**
	 * 删除
	 * @param sId 记录编号
	 * @param iVersion 数据版本号
	 * @return MsgEmity
	 */
	@Transactional
	@Override
	public MsgEmity del(String sId, Integer iVersion) {
		int code = 7000;
		try {
			int i = goodsMakeMapper.del(sId, iVersion);
			if (i < 1) {
				Integer k = goodsMakeMapper.getiVersion(sId);//如果删除的影响数小于1,则检查数据是否存在
				if (null == k) {
					return new MsgEmity(true, "成功，数据已经删除！", 7999);//删除影响数失败,但数据也不存在则视为成功
				}
				
				if (!iVersion.equals(k)) {
					return new MsgEmity(false, "删除数据失败，系统中的数据可能已经被更新！", 7001);
				}

				Log.error("删除未能得到预期影响值(预期1):", i);
				return new MsgEmity(false, "删除数据失败！", 7002);
			}

			code = 7003;
			i = goodsMakeMapper.delStockIn(sId);
			if (i < 1) {
				code = 7004;
				Log.error("删除入库操作未能得到预期影响值(预期1):", i);
				throw new RuntimeException("删除入库失败！");
			}
			
			i = goodsMakeMapper.rollbackStock(sId);
			if (i < 1) {
				code = 7005;
				Log.error("回退库存操作未能得到预期影响值(预期1):", i);
				throw new RuntimeException("回退库存失败！");
			}
		} catch (Exception e) {
			Log.error("删除时发生异常:", e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚
			return new MsgEmity(false, "删除失败！", code);
		}
		
		return new MsgEmity(true, "删除成功！", 7999);
	}

	/**
	 * 根据Id查询数据
	 * @param sId
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findById(String sId) {
		GoodsMake goodsMake = null;
		try {
			goodsMake = goodsMakeMapper.findById(sId);
			if (null == goodsMake) {
				return new MsgEmity(false, "数据不存在！", 7001);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", goodsMake);
	}

	/**
	 * 根据字段名取指定记录编号的数据库表中对应字段的值
	 * @param sId
	 * @param fieldNames 待取数据的字段名称集合
	 * @return MsgEmity 返回内容data中存放的是Map
	 */
	@Override
	public MsgEmity getValueByFieldName(String sId, List<String> fieldNames) {
		//--检查实体类中是否有该字段,没有就不加入查询字段--//
		Class<?> clazz = GoodsMakeBase.class;
		List<String> dbNames = new ArrayList<String>();
		for (String field : fieldNames) {
			try {
				if (clazz.getDeclaredField(field) != null) {
					dbNames.add(field);
				}
			} catch (Exception e) {
			}
		}
		
		if (dbNames.size() < 1) {
			return new MsgEmity(false, "没有对应的数据可查询！", 7001);
		}
		
		Map<String, Object> result = null;
		try {
			result = goodsMakeMapper.getValueByFieldName(sId, dbNames);
			if (null == result) {
				return new MsgEmity(false, "数据不存在！", 7002);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7003);
		}
		
		//--补充字段--//
		for (String string : fieldNames) {
			if (!result.containsKey(string)) {
				result.put(string, null);
			}
		}
		
		return new MsgEmity(true, "查询成功！", result);
	}

	/**
	 * 根据关键值取对象集合
	 * @param goodsMakeData 存放查询条件的GoodsMake对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByKey(GoodsMake goodsMakeData) {
		List<GoodsMake> list = null;
		try {
			list = goodsMakeMapper.findByKey(goodsMakeData);
			if (null == list) {
				return new MsgEmity(false, "数据不存在！", 7001);
			}
			if (list.size() < 1) {
				return new MsgEmity(true, "查询成功，但没有数据！", list);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", list);
	}

	/**
	 * 根据关键值查数量
	 * @param goodsMakeData 存放查询条件的GoodsMake对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findCountByKey(GoodsMake goodsMakeData) {
		int iCount = 0;
		try {
			iCount = goodsMakeMapper.findCountByKey(goodsMakeData);
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7001);
		}
		
		return new MsgEmity(true, "查询成功！", iCount);
	}

	/**
	 * 检查待新增内容是否存在重复数据
	 * @param goodsMakeData
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity checkRepeatByAdd(GoodsMake goodsMakeData) {
		int i = 0;
		try {
			i = goodsMakeMapper.checkRepeatByAdd(goodsMakeData);
			if (0 == i) {
				return new MsgEmity(false, "查询成功！没发现重复", 7007);
			}
		} catch (Exception e) {
			Log.error("检查待新增内容是否存在重复数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败，请查看异常日志", 7008);
		}
		
		return new MsgEmity(true, "查询成功！发现重复", i);//将查询到的数量(或sql中的构造码)返回以便特殊业务要求
	}
	
	/**
	 * 查询分页信息
	 * @param page 分页信息对象
	 * @param orders 排序数据集合
	 * @param sLikeStr 全文检索
	 * @param condition 查询条件对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByPage(Page page, OrderInfoList orders, String sLikeStr,
			ConditionGoodsMake condition) {
		if ("配置文件中的当前库全文检索时间范围dLikeDate未设置".equals(sLikeDate)) {
			sLikeDate = "3";
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DATE, - IntegerUtil.strToInt(sLikeDate, 3));//日期加m天
		Date dLikeDateSt = calendar.getTime();
		Date dLikeDateEd = new Date();
		
		int iCount = 0;
		try {
			iCount = goodsMakeMapper.findByPageCount(sLikeStr, dLikeDateSt, dLikeDateEd, condition);
		} catch (Exception e) {
			Log.error("查询数量发生异常", e.getMessage());
			return new MsgEmity(false, "查询数量失败！", 7001);
		}
		
		if (iCount < 1) {
			return new MsgEmity(true, "没有相关数据！", page);
		}

		page.setCountRow(iCount);

		List<GoodsMake> list = null;
		try {
			list = goodsMakeMapper.findByPage(page,
					(null == orders) ? null : orders.getOrderInfoList(),
					sLikeStr, dLikeDateSt, dLikeDateEd, condition);
			if (null == list) {
				Log.error("查询数据发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7002);
			}
		} catch (Exception e) {
			Log.error("查询分页数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7003);
		}

		page.setRecordList(list);
		
		if (null != sLikeStr) {
			return MsgEmity.success(page, "查询成功！", "由于使用了全文检索,因此数据查询限制为近", sLikeDate, "天创建的数据");
		}
		
		return new MsgEmity(true, "查询成功！", page);
	}
	
	/**
	 * 直接调用数据库操作
	 * @param funName 待调用的mybits函数名
	 * @param argsType 参数类型集合
	 * @param args 参数集合
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity callMapping(String funName, Class<?>[] argsType , Object[] args) {
		if (!ClassUtil.containsMethod(GoodsMakeMapper.class, funName)) {//先判断是否存在方法
			return new MsgEmity(false, "系统中没有所请求的处理方法，请联系管理员！", 7001);
		}
		
		Object object = null;
		try {
			object = GoodsMakeMapper.class.getDeclaredMethod(funName, argsType )
					.invoke(goodsMakeMapper, args);

			if (null == object) {
				Log.error("执行数据库操作'", funName, "'发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "执行失败！", 7002);
			}
		} catch (Exception e) {
			Log.error("执行数据库操作'", funName, "'发生异常:", e.getMessage());
			return new MsgEmity(false, "执行请求失败！", 7003);
		}
		
		return new MsgEmity(true, "执行成功！", object);
	}
	
	/**
	 * 根据记录编号查询符合分页数据的某条记录
	 * @param sId 记录编号
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByPageRow(String sId) {
		GoodsMake goodsMake = null;
		try {
			goodsMake = goodsMakeMapper.findByPageRow(sId);
			if (null == goodsMake) {
				return new MsgEmity(false, "数据不存在！", 7001);
			}
		} catch (Exception e) {
			Log.error("查询发生异常:", e.getMessage());
			return new MsgEmity(false, "查询失败！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", goodsMake);
	}
	
	/**
	 * 查询搜索用的数据
	 * 警告:本方法只允许内部使用,不能开放到外部接口
	 * @param whereStr 查询条件字符串
	 * @param orders 排序数据集合
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findBySearch(String whereStr, OrderInfoList orders) {
		if (null == whereStr || "".equals(whereStr.trim())) {
			return new MsgEmity(false, "查询条件不允许为空！", 7001);
		}

		List<GoodsMake> list = null;
		try {
			list = goodsMakeMapper.findBySearch(whereStr.trim(),
					(null == orders) ? null : orders.getOrderInfoList());
			if (null == list) {
				Log.error("查询数据发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7002);
			}
		} catch (Exception e) {
			Log.error("查询分页数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7003);
		}
		
		return new MsgEmity(true, "查询成功！", list);
	}

	/**
	 * 查询导出到文件的数据
	 * @param orders 排序数据集合
	 * @param sLikeStr 全文检索
	 * @param condition 查询条件对象
	 * @return MsgEmity
	 */
	@Override
	public MsgEmity findByExport(OrderInfoList orders, String sLikeStr, ConditionGoodsMake condition) {
		if ("配置文件中的当前库全文检索时间范围dLikeDate未设置".equals(sLikeDate)) {
			sLikeDate = "3";
		}
		
		Calendar calendar = Calendar.getInstance();
		calendar.setTime(new Date());
		calendar.add(Calendar.DATE, - IntegerUtil.strToInt(sLikeDate, 3));//日期加m分
		Date dLikeDateSt = calendar.getTime();
		Date dLikeDateEd = new Date();
		
		List<GoodsMake> list = null;
		try {
			list = goodsMakeMapper.findByExport(
					(null == orders) ? null : orders.getOrderInfoList(),
					sLikeStr, dLikeDateSt, dLikeDateEd, condition);
			if (null == list) {
				Log.error("查询数据发生异常,执行的返回值为:null,预期值不应为null");
				return new MsgEmity(false, "查询操作失败！", 7001);
			}
		} catch (Exception e) {
			Log.error("查询导出文件用的数据发生异常:", e.getMessage());
			return new MsgEmity(false, "查询请求失败，请查看异常日志！", 7002);
		}
		
		return new MsgEmity(true, "查询成功！", list);
	}

	//---------------------------- 自动生成代码结束 ----------------------------//

	/**
	 * 作废生产单
	 * @param sId
	 * @param iVersion
	 * @return
	 */
	@Transactional
	@Override
	public MsgEmity nullify(String sId, Integer iVersion) {
		int code = 7000;
		try {
			int i = goodsMakeMapper.nullify(sId, iVersion);
			if (i < 1) {
				Integer k = goodsMakeMapper.getiVersion(sId);//如果删除的影响数小于1,则检查数据是否存在
				if (!iVersion.equals(k)) {
					return new MsgEmity(false, "生产记录'作废'操作失败，系统中的数据可能已经被更新！", 7001);
				}

				code = 7002;
				Log.error("生产记录'作废'操作未能得到预期影响值(预期1):", i);
				throw new RuntimeException("生产记录'作废'操作失败！");
			}
			
			i = goodsMakeMapper.nullifyStockIn(sId);
			if (i < 1) {
				code = 7003;
				Log.error("入库记录'作废'操作未能得到预期影响值(预期1):", i);
				throw new RuntimeException("生产记录'作废'操作失败！");
			}

			i = goodsMakeMapper.rollbackStock(sId);
			if (i < 1) {
				code = 7004;
				Log.error("回退库存操作未能得到预期影响值(预期1):", i);
				throw new RuntimeException("回退库存失败！");
			}
		} catch (Exception e) {
			Log.error("作废生产单操作发生异常:", e.getMessage());
			TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();//手动回滚
			return new MsgEmity(false, "作废生产单请求失败！", code);
		}
		
		return new MsgEmity(true, "作废生产单请求成功！", iVersion +1);
	}

}
